a:=[[1,2],[3,4]];
b:=[[5,6],[7,8]];
[ [ 1, 2 ], [ 3, 4 ] ]
[ [ 5, 6 ], [ 7, 8 ] ]
Hecho con Quarto
Las matrices en gap
se representan como una lista de listas, de forma que todas ellas tengan la misma longitud y el mismo tipo de elementos. Por tanto hay que tener cuidado con qué comandos son ‘destructivos’. La suma, producto e inverso se calculan con las operaciones usuales.
Esto cambiará en las versiones futuras de gap
(véase el proyecto MatrixObj).
Y el determinante
Para calcular la forma normal de Hermite sobre los enteros disponemos de la siguiente función.
Si queremos las matrices te transformaciones para llegar a la forma de Hermite:
rec( normal := [ [ 1, 2, 3 ], [ 0, 3, 6 ] ], rank := 2, rowC := [ [ 1, 0 ], [ 0, 1 ] ], rowQ := [ [ 1, 0 ], [ 4, -1 ] ], rowtrans := [ [ 1, 0 ], [ 4, -1 ] ] )
Si queremos hacer el cálculo sobre los racionales, usamos TriangulizeMat
, pero ojo, que esta función destruye el argumento que le pasamos.
Con TriangulizedMat
el argumento no se modifica.
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 1st choice method found for `TriangulizedMat' on 1 arguments at /home/pedro/lib/gap-4.10.0/lib/methsel2.g:250 called from
<function "HANDLE_METHOD_NOT_FOUND">( <arguments> )
called from read-eval loop at stream:1
El error se debe a que en este caso a
es una lista de listas con enteros (que no se consideran polinomios) y un polinomio (x
). Para arreglar esto, multiplicamos toda la matriz por One(P)
convirtiendo todos los enteros en polinomios (constantes).
Si queremos hacer las cuentas sobre un cuerpo finito, podemos usar el comando GF
(cuerpo de Galois), y luego embeber la matriz dada en dicho cuerpo con One
.
[ [ ZmodnZObj(1,7), ZmodnZObj(0,7), ZmodnZObj(6,7) ], [ ZmodnZObj(0,7), ZmodnZObj(1,7), ZmodnZObj(2,7) ] ]
Nótese que a
no ha sido destruida, pues la operación a*One(F)
genera una nueva matriz a partir de ella.
Para encontrar una solución de un sistema de la forma \(x A=b\) usando gap
, utilizamos el comando SolutionMat
junto con NullspaceMat
. El primero nos da una solución particular (en caso de existir) y el segundo nos da las soluciones del sistema homogéneo asociado.
Con lo que en este caso la solución es única.
Y en este caso las soluciones son de la forma \((-\frac{1}2,\frac{1}2,0)+\lambda (1,-2,1)\).
En caso de no existir solución recibimos un fail
a cambio.
También podemos hacer las cuentas sobre un cuerpo finito.
gap
ya sabe que algunos de sus objetos son espacios vectoriales, y además podemos definir nuevos espacios vectoriales de diferentes formas.
InstallMethod(ViewString, [IsPolynomial], String);
InstallMethod(ViewString, [IsVectorSpace], function(v) return("Espacio vectorial"); end);
InstallMethod(ViewString, [IsSubspacesVectorSpace], function(v) return("Subespacios vectoriales"); end);
InstallMethod(ViewString, [IsGeneralMapping], function(v) return("Aplicación"); end);
También podemos calcular los coeficientes de un vector respecto de una base, o las combinaciones lineales de los elementos de una base.
Los subespacios se pueden definir con la orden Subspace
, y los cocientes se hacen como en grupos.
Podemos hacer cocientes:
También intersecciones y sumas
Si nuestro espacio vectorial es finito, podemos calcular todos sus subespacios.
[ [ ], [ [ ZmodnZObj(1,2), ZmodnZObj(0,2) ] ], [ [ ZmodnZObj(1,2), ZmodnZObj(1,2) ] ], [ [ ZmodnZObj(0,2), ZmodnZObj(1,2) ] ], [ [ ZmodnZObj(1,2), ZmodnZObj(0,2) ], [ ZmodnZObj(0,2), ZmodnZObj(1,2) ] ] ]
[ [ ], [ [ ZmodnZObj(1,2), ZmodnZObj(0,2) ] ], [ [ ZmodnZObj(1,2), ZmodnZObj(1,2) ] ], [ [ ZmodnZObj(0,2), ZmodnZObj(1,2) ] ], [ [ ZmodnZObj(1,2), ZmodnZObj(0,2) ], [ ZmodnZObj(0,2), ZmodnZObj(1,2) ] ] ]
[ [ [ ZmodnZObj(0,2), ZmodnZObj(0,2) ] ], [ [ ZmodnZObj(0,2), ZmodnZObj(0,2) ], [ ZmodnZObj(1,2), ZmodnZObj(0,2) ] ], [ [ ZmodnZObj(0,2), ZmodnZObj(0,2) ], [ ZmodnZObj(1,2), ZmodnZObj(1,2) ] ], [ [ ZmodnZObj(0,2), ZmodnZObj(0,2) ], [ ZmodnZObj(0,2), ZmodnZObj(1,2) ] ], [ [ ZmodnZObj(0,2), ZmodnZObj(0,2) ], [ ZmodnZObj(0,2), ZmodnZObj(1,2) ], [ ZmodnZObj(1,2), ZmodnZObj(0,2) ], [ ZmodnZObj(1,2), ZmodnZObj(1,2) ] ] ]
Para definir una aplicación lineal entre subespacios podemos usar la función LeftModuleGeneralMappingByImages
, pues en gap
, los espacios vectoriales son considerados como módulos a izquierda.
Un complemento de un subespacio \(W\) de \(V\) lo podemos calcular usando el homomorfismo natural de \(V\) a \(V/W\).
( Rationals^4 )
Espacio vectorial
Aplicación
Al no ser la aplicación biyectiva no podemos usar PreImage
a secas.
V1:=Rationals^4;;
V2:=VectorSpace(Rationals,[[1,2],[3,4]]);;
f:=LeftModuleGeneralMappingByImages(V1,V2,Basis(V1), [[1,2],[3,4],[1,0],[0,1]]);
( Rationals^4 )
Espacio vectorial
Aplicación
Y teorema de isomorfía al canto…
También podemos usar notación matricial.
Veamos cómo calcular el polinomio característico y sus ceros.
[ [ ZmodnZObj(1,7), ZmodnZObj(0,7), ZmodnZObj(1,7) ], [ ZmodnZObj(3,7), ZmodnZObj(1,7), ZmodnZObj(0,7) ], [ ZmodnZObj(0,7), ZmodnZObj(1,7), ZmodnZObj(0,7) ] ]
Comprobemos si a
es diagonalizable, para ello calculamos sus subespacios propios.
[ [ [ ZmodnZObj(3,7), ZmodnZObj(6,7), ZmodnZObj(1,7) ] ], [ [ ZmodnZObj(2,7), ZmodnZObj(5,7), ZmodnZObj(1,7) ] ] ]
Como vemos, el elemento \(5\in \mathbb{Z}_7\) es una raíz doble cuyo subespacio propio tiene dimensión uno, por lo que la matriz no es diagonalizable.
Veamos otro ejemplo que sí es diagonalizable.
[ [ [ 0, 1, 0 ], [ 1, 0, 1 ] ], [ [ -1/3, 0, 1 ] ] ]